function colorValue(min: number) {
  return Math.floor(Math.random() * 255 + min);
}
function createColorStyle(
  r: string | number,
  g: string | number,
  b: string | number
) {
  return "rgba(" + r + "," + g + "," + b + ", 0.8)";
}
class Color {
  r: number;
  g: number;
  b: number;
  style: string;
  constructor(min: number = 0) {
    this.r = colorValue(min);
    this.g = colorValue(min);
    this.b = colorValue(min);
    this.style = createColorStyle(this.r, this.g, this.b);
  }
}
class Dot {
  x: number;
  y: number;
  vx: number;
  vy: number;
  radius: number;
  color: any;
  constructor(canvas: HTMLCanvasElement) {
    this.x = Math.random() * canvas.width;
    this.y = Math.random() * canvas.height;
    this.vx = -0.5 + Math.random();
    this.vy = -0.5 + Math.random();
    this.radius = Math.random() * 2;
    this.color = new Color();
  }
  draw(ctx: CanvasRenderingContext2D) {
    ctx.beginPath();
    ctx.fillStyle = this.color.style;
    ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, false);
    ctx.fill();
  }
}
export default window.onload = function () {
  // 定义body的margin由默认值8px->0px
  document.body.style.margin = "0";
  document.body.style.background = "#30333F";
  // 创建canvas画布
  document.body.appendChild(document.createElement("canvas"));
  const canvas = document.querySelector("canvas") as HTMLCanvasElement;
  const ctx = canvas.getContext("2d") as CanvasRenderingContext2D; // ctx返回一个在canvas上画图的api/dom
  canvas.width = window.innerWidth;
  canvas.height = window.innerHeight;
  canvas.style.position = "fixed";
  ctx.lineWidth = 0.3;
  ctx.strokeStyle = new Color(150)?.style;
  // 定义鼠标覆盖范围
  const mousePosition = {
    x: (30 * canvas.width) / 100,
    y: (30 * canvas.height) / 100,
  };
  const dots = {
    nb: 1000, // Dot的总数
    distance: 50,
    d_radius: 100,
    array: [],
  };
  // 创建颜色类，Color类返回字符串型rgba（*,*,*,.8）
  function mixComponents(
    comp1: number,
    weight1: number,
    comp2: number,
    weight2: number
  ) {
    return (comp1 * weight1 + comp2 * weight2) / (weight1 + weight2);
  }
  function averageColorStyles(dot1: any, dot2: any) {
    const color1 = dot1.color;
    const color2 = dot2.color;

    const r = mixComponents(color1.r, dot1.radius, color2.r, dot2.radius);
    const g = mixComponents(color1.g, dot1.radius, color2.g, dot2.radius);
    const b = mixComponents(color1.b, dot1.radius, color2.b, dot2.radius);
    return createColorStyle(Math.floor(r), Math.floor(g), Math.floor(b));
  }

  function moveDots() {
    // Dot对象的移动
    for (let i = 0; i < dots.nb; i++) {
      const dot: any = dots.array[i];

      if (dot.y < 0 || dot.y > canvas.height) {
        dot.vy = -dot.vy;
      } else if (dot.x < 0 || dot.x > canvas.width) {
        dot.vx = -dot.vx;
      }
      dot.x += dot.vx;
      dot.y += dot.vy;
    }
  }
  function connectDots() {
    // DOt对象的连接
    for (let i = 0; i < dots.nb; i++) {
      for (let j = i; j < dots.nb; j++) {
        const iDot: any = dots.array[i];
        const jDot: any = dots.array[j];

        if (
          iDot.x - jDot.x < dots.distance &&
          iDot.y - jDot.y < dots.distance &&
          iDot.x - jDot.x > -dots.distance &&
          iDot.y - jDot.y > -dots.distance
        ) {
          if (
            iDot.x - mousePosition.x < dots.d_radius &&
            iDot.y - mousePosition.y < dots.d_radius &&
            iDot.x - mousePosition.x > -dots.d_radius &&
            iDot.y - mousePosition.y > -dots.d_radius
          ) {
            ctx.beginPath();
            ctx.strokeStyle = averageColorStyles(iDot, jDot);
            ctx.moveTo(iDot.x, iDot.y);
            ctx.lineTo(jDot.x, jDot.y);
            ctx.stroke(); // 绘制定义的路线
            ctx.closePath(); // 创建从当前点回到起始点的路径
          }
        }
      }
    }
  }
  function createDots() {
    // 创建nb个Dot对象
    for (let i = 0; i < dots.nb; i++) {
      dots.array.push(new Dot(canvas));
    }
  }
  function drawDots() {
    // 引用Dot原型链，使用draw方法，在canvas上画出Dot对象
    for (let i = 0; i < dots.nb; i++) {
      const dot: any = dots.array[i];
      dot.draw();
    }
  }
  function animateDots() {
    ctx.clearRect(0, 0, canvas.width, canvas.height); // 清除画布，否则线条会连在一起
    moveDots();
    connectDots();
    drawDots();
    requestAnimationFrame(animateDots);
  }
  createDots(); // 使用创建Dot类函数
  requestAnimationFrame(animateDots); // 使用canvas独有的60Hz刷新屏幕画布的方法

  document.querySelector("canvas").addEventListener("mousemove", function (e) {
    mousePosition.x = e.pageX;
    mousePosition.y = e.pageY;
  });

  document.querySelector("canvas").addEventListener("mouseleave", function () {
    // 鼠标离开时，连接自动返回到画布中心
    mousePosition.x = canvas.width / 2;
    mousePosition.y = canvas.height / 2;
  });
};
